package org.example.wikwok.service.impl;

import org.example.wikwok.common.ReturnedMessage;
import org.example.wikwok.mapper.*;
import org.example.wikwok.pojo.*;
import org.example.wikwok.common.AESE;
import org.example.wikwok.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.crypto.SecretKey;
import java.util.ArrayList;
import java.util.List;

import static org.example.wikwok.common.AESE.decodeKeyFromBase64;


@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AESEKeyMapper aeseKeyMapper;
    //获取用户视频信息
    @Autowired
    private VideoMapper videoMapper;
    //获取用户关注信息
    @Autowired
    private FollowMapper followMapper;
    //获取用户点赞信息
    @Autowired
    private LikeMapper likeMapper;
    @Autowired
    private CollectMapper collectMapper;
    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private Secondary_CommentMapper secondary_commentMapper;
    @Autowired
    private OperationLogMapper operationLogMapper;
     @Override
     public User Login( String name, String password) throws Exception {
         int id=userMapper.selectIdByName(name);
         //check if user exists in database
         if(userMapper.selectByPrimaryKey(id).getName()==null) return null;
         //decrypt password
         SecretKey retrievedKey = decodeKeyFromBase64(aeseKeyMapper.selectByPrimaryKey(id).getAkey());
         String decryptedPassword = AESE.decrypt(userMapper.selectByPrimaryKey(id).getPassword(),retrievedKey);
         if(decryptedPassword.equals(password)){
             operationLogMapper.insert(OperationLog.build("User login", id, ReturnedMessage.USERLOGINSUCCESS));
             return userMapper.selectByPrimaryKey(id);
         }else {
             operationLogMapper.insert(OperationLog.build("User login", id, ReturnedMessage.USERLOGINFAILED));
             return null;
         }
     }
     @Override
     public boolean Register(String name, String password) {
         if(!userMapper.selectByName(name).isEmpty())return false;
         try{
             //encrypt password
             SecretKey key = AESE.generateKey(128);
             String encryptedPassword = AESE.encrypt(password,key);
             //insert user into database
             userMapper.insert(new User(name,encryptedPassword,null,null));
             //insert key into database
             String encodedKey = AESE.encodeKeyToBase64(key);
             aeseKeyMapper.insert(new AESEKey(userMapper.selectIdByName(name),encodedKey));
             operationLogMapper.insert(OperationLog.build("User register",userMapper.selectIdByName(name) , ReturnedMessage.USERREGISTEREDSUCCESS));
             return true;
         }catch(Exception e){
             operationLogMapper.insert(OperationLog.build("User register",userMapper.selectIdByName(name) , ReturnedMessage.USERREGISTEREDFAILED));
             return false;
         }
     }

     @Override
     public boolean UpdateUserPassword(int id, String OldPassword, String NewPassword) throws Exception {
         if(userMapper.selectByPrimaryKey(id).getName()==null) return false;
         SecretKey retrievedKey = decodeKeyFromBase64(aeseKeyMapper.selectByPrimaryKey(id).getAkey());
         //check if old password is correct
         if(AESE.decrypt(userMapper.selectByPrimaryKey(id).getPassword(),retrievedKey).equals(OldPassword)) {
                 //encrypt new password
                 String encryptedPassword = AESE.encrypt(NewPassword,retrievedKey);
                 User record=userMapper.selectByPrimaryKey(id);
                 record.setPassword(encryptedPassword);
                 //update password in database
                 userMapper.updateByPrimaryKey(record);
                 operationLogMapper.insert(OperationLog.build("User update password", id, ReturnedMessage.USERUPDATEDPASSWORDSUCCESS));
                 return true;
         }
         else {
             operationLogMapper.insert(OperationLog.build("User update password", id, ReturnedMessage.USERUPDATEPASSWORDFAILED));
             throw new Exception("Incorrect password(1303)");
         }
     }


    @Override
    public void Logout(int id) {
        if(userMapper.selectByPrimaryKey(id).getName()==null) return;
        userMapper.deleteByPrimaryKey(id);
    }

    @Override
    public UserInfo getUserInfo(int userId) {
        UserInfo userInfo=new UserInfo();
        User user=userMapper.selectByPrimaryKey(userId);
        if(user.getName()==null) return null;
        //设置基本属性并返回
        userInfo.setUser(new User(user.getId(),user.getName(),user.getImgurl(),user.getDescrip()));
        List<Video> LikedVideos=videoMapper.selectlikedvideos(userId);
        List<Video>UploadedVideos=videoMapper.selectByUploaderId(userId);
        List<VideoInfo>LikedVideoInfos= new ArrayList<>();
        List<VideoInfo>UploadedVideoInfos= new ArrayList<>();
        for(Video video:LikedVideos){
            LikedVideoInfos.add(new VideoInfo(video,likeMapper.selectCountByVideoId(video.getId()),collectMapper.selectCountByVideoId(video.getId()),commentMapper.selectCountByVideoId(video.getId())+secondary_commentMapper.selectByVideoId(video.getId()),userMapper.selectByPrimaryKey(video.getUploaderid())));
        }
        for(Video video:UploadedVideos){
            UploadedVideoInfos.add(new VideoInfo(video,likeMapper.selectCountByVideoId(video.getId()),collectMapper.selectCountByVideoId(video.getId()),commentMapper.selectCountByVideoId(video.getId())+secondary_commentMapper.selectByVideoId(video.getId()),userMapper.selectByPrimaryKey(video.getUploaderid())));
        }
        userInfo.setLikedVideos(LikedVideoInfos);
        userInfo.setLikedUpMasters(userMapper.selectlikedUpMaster(userId));
        userInfo.setUploadedVideos(UploadedVideoInfos);
        userInfo.setFollowers(followMapper.selectFollowedCount(userId));
        userInfo.setFollowing(likeMapper.selectUserLikeCount(userId));
        operationLogMapper.insert(OperationLog.build("User get info", userId, ReturnedMessage.USERINFOSUCCESS));
        return userInfo;
    }

    @Override
    public boolean UpdateUserInfo(int userId, String userName, String imgUrl, String descrip) {
        if(userMapper.selectByPrimaryKey(userId).getName()==null) return false;
        try{
        User record=userMapper.selectByPrimaryKey(userId);
        record.setName(userName);
        record.setImgurl(imgUrl);
        record.setDescrip(descrip);
        userMapper.updateByPrimaryKey(record);
        operationLogMapper.insert(OperationLog.build("User update info", userId, ReturnedMessage.USERUPDATEDINFOSUCCESS));
        return true;
        }
        catch(Exception e){
            operationLogMapper.insert(OperationLog.build("User update info", userId, ReturnedMessage.USERUPDATEINFOFAILED));
            return false;
        }
    }
}
